//
//  OverlayViewController.m
//  POCRA
//
//  Created by Marcel Arbó Lack on 26/11/10.
//  Copyright 2010 Mobivery. All rights reserved.
//


#import <QuartzCore/QuartzCore.h>
#import "OverlayViewController.h"
#import "ARGeoCoordinate.h"
#import "Defines.h"
#import "ListFlat.h"

@interface OverlayViewController(Private)
- (void)orientationChanged:(NSNotification *)notification;
// Cambia el aspecto de la vista de RA rotandola
- (void)rotateRAViewAcordingToOrientation:(BOOL)IsLandscape;
// Anyade las vistas giratorias si es la primera vez que se entra en la vista
- (void)addViewsIfFirstTime;
@end

static BOOL firstAddingViews;

@implementation OverlayViewController

@synthesize tagSelected;
@synthesize overlayDelegate = overlayDelegate_;

- (void)dealloc {
	
	[radarController_ release];
	[backButton_ release]; backButton_ = nil;
	[resultTable_ release]; resultTable_ = nil;
	[tagDetail_ release];
	
    [super dealloc];
}

- (id)initWithImagePicker:(UIImagePickerController*)picker {
	if (!(self = [super init])) return nil;
	
	[self setCameraController:picker];
	
	self.debugMode = NO;	
	self.scaleViewsBasedOnDistance = YES;
	self.minimumScaleFactor = .5;
	
	self.rotateViewsBasedOnPerspective = YES;
	
	return self;
}

- (id)initWithImagePicker:(UIImagePickerController*)picker AndLocationMan:(CLLocationManager *)manager {
	
	if (!(self = [super initWithLocationManager:manager])) return nil;
		
	[self setCameraController:picker];
	
	self.debugMode = NO;	
	self.scaleViewsBasedOnDistance = YES;
	self.minimumScaleFactor = .5;
	
	self.rotateViewsBasedOnPerspective = YES;

	return self;
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	
    [super viewDidLoad];
	
	tagSelected = 0;
	
	// Imagenes del boton de 'salir' de la vista RA
	UIImage *buttonBackground = [UIImage imageNamed:@"RA_btn_back.png"];
	UIImage *newPressedImage = [buttonBackground stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];
	
	// Boton de 'salir' de la vista RA
	backButton_ = [[UIButton alloc] initWithFrame:CGRectMake(10.0, 20.0, 39, 39.0)];
	[backButton_ setBackgroundImage:buttonBackground forState:UIControlStateNormal];
	[backButton_ setBackgroundImage:newPressedImage forState:UIControlStateSelected];	
	[backButton_ addTarget:self action:@selector(closeARView) forControlEvents:UIControlEventTouchUpInside];
	[backButton_ setBackgroundColor:[UIColor clearColor]];
	
	// Se anyade el boton
	[self.view addSubview:backButton_];
	
	isShowingLandscapeView_ = NO;
	
	// Preparamos al controlador para que capture los eventos de girar el iPhone.
	[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)
												 name:UIDeviceOrientationDidChangeNotification object:nil];
	
	firstAddingViews = YES;
	
}

- (void)unloadView {
	
	[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
	
	[backButton_ removeFromSuperview];
	[radarController_ resetRadar];
	[radarController_.view removeFromSuperview];
	
	[self._updateTimer invalidate]; 
	self._updateTimer = nil;
	
	for (int i=0;i<[[self coordinates] count];i++) {
		
		// Recogemos las vistas ya creadas
		UIView *viewToDraw = [self GetCoordinateView:i];
		UIButton *buttonToDraw = [self GetCoordinateButton:i];
		
		// Las ocultamos
		[viewToDraw setHidden:YES];
		[buttonToDraw setHidden:YES];
		
		// Y si no tienen vista padre, es decir, no han sido anyadidos a ninguna vista
		if (viewToDraw.superview) {
			
			// Se eliminan las vistas
			[viewToDraw removeFromSuperview];
			[buttonToDraw removeFromSuperview];
			
		}
	}
	
	[super unloadView];
}

// Redifinimos este metodo para indicar que modos de oritentacion de iPhone permitimos y se trasmita a elementos como el teclado, msg, etc.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
	
	// Si estamos en los pasos 2 y 3 soportamos todos los tipos de orientacion.
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark -
#pragma mark Metodos definidos en la interfaz

// Carga en la vista de RA una lista de puntos que sigue el protocolo AugmentedRealityDataModelAccess
- (void)loadDataModelAccessArray:(NSArray*)resultTable maximumTags:(NSInteger)numberOfTags {

	NSMutableArray *tempLocationArray = [[NSMutableArray alloc] init];
	NSInteger counter = 0;
	self.maximumScaleDistance = 0;
	
	if(numberOfTags != 0)
	{
		resultTable_ = [[NSMutableArray alloc] initWithArray:resultTable];
		
		// Para cada unidad que se quiere colocar en el visor de RA
		for(ListFlat *baseDataAccess in resultTable_)
		{
			// Solo metemos el maximo numero permitido
			if (counter == numberOfTags ) {
				
				// Salimos del bucle si hay demasiados
				break;
			}
			
			counter ++;
			
			// Se recoge punto por punto para obtener sus propiedades

			// Localizacion de punto
			CLLocation * tempLocation = [[CLLocation alloc] initWithLatitude:[baseDataAccess latitude] 
																	longitude:[baseDataAccess longitude]];
			
			// Creacion del punto RA y establecimiento de parametros			
			ARGeoCoordinate *tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation];
			tempCoordinate.title = [NSString stringWithFormat:@"%.0f €",[baseDataAccess price]];
			//tempCoordinate.subtitle = [baseDataAccess street];
			tempCoordinate.aditionalInfo = [baseDataAccess street];
			tempCoordinate.distancePA = [NSString stringWithFormat:@"%.0f m",[baseDataAccess distance]];
			tempCoordinate.index = counter;
			
			[tempLocationArray addObject:tempCoordinate];
			[tempLocation release];
			
		}
	}
	
	// Se anyaden todos los puntos del array rellenado anteriormente
	[self addCoordinates:tempLocationArray];

	// Se establece el centro del visor de RA
	CLLocation *newCenter = [[CLLocation alloc] initWithLatitude:self.locationManager.location.coordinate.latitude 
														longitude:self.locationManager.location.coordinate.longitude];	
	[self setCenterLocation:newCenter];
	[newCenter release];
	
	// Se crea el radar
	radarController_ = [[ARradarViewController alloc] initWithNibName:@"ARradarView" bundle:nil];
	radarController_.view.frame = CGRectMake(235.0, 395.0, radarController_.view.frame.size.width, radarController_.view.frame.size.height);	
	[radarController_ setRadarPoints:tempLocationArray MaxScaleDistance:self.maximumScaleDistance];
	
	// Se anyade a la vista
	[self.view addSubview:radarController_.view];
	
	radarHidden_ = YES;	
	firstAddingViews = YES;
	
	[tempLocationArray release];
	
}

// Cambia la inclinacion del visor
- (BOOL)changeInclination:(BOOL)ARloaded {
	
	double centerInclination;
	double bottomInclination;
	double topInclination;
	BOOL resultinclination;
	
	// Si no esta el visor RA cargado (creo que aqui no entrara nunca)
	if (ARloaded == NO) {
		
		centerInclination = self.centerCoordinate.inclination;
		bottomInclination = centerInclination - VIEWPORT_HEIGHT_RADIANS / 3.0 ;
		topInclination = centerInclination + VIEWPORT_HEIGHT_RADIANS / 3.0 ;
		
		//NSLog(@"top:%f bottom:%f",topInclination,bottomInclination);
	} else {
		
		// El visor RA esta cargado		
		centerInclination = self.centerCoordinate.inclination;
		bottomInclination = (centerInclination + M_PI/2) - VIEWPORT_HEIGHT_RADIANS / 2.0 ;
		topInclination = (centerInclination + M_PI/2) + VIEWPORT_HEIGHT_RADIANS / 2.0 ;
		
		//NSLog(@"top:%f bottom:%f",topInclination,bottomInclination);
	}
	
	resultinclination = (0.0 > bottomInclination && 0.0 < topInclination);
	
	return resultinclination;
	
}

// Devuelve el nombre del tag seleccionado
- (NSString*)getVectorName {
	
	ARRotatingViewController *tagcontroller;	
	tagcontroller = (ARRotatingViewController*)[self getTagController:tagSelected-1];
	
	return [tagcontroller GetMyNameTag];
	
}

// Devuelve la distancia del vector seleccionado
- (NSString*)getVectorDistance {
	
	ARRotatingViewController *tagcontroller;	
	tagcontroller = (ARRotatingViewController*)[self getTagController:tagSelected-1];
	
	return [tagcontroller GetMyDistanceTag];
	
}

- (BOOL)IsOrientedActived {
	
	return [tagDetail_ IsOrientationActive];
	
}

// Cierra la vista de realidad aumentada
- (void)closeARView {
	
	[overlayDelegate_ exitRAView];
	
}

// Muestra u oculta la vista detalle
- (void)showHideDetailView:(BOOL)showView {
	
	// Se obtiene el boton relacionado con el detalle
	UIButton *buttonToDraw = [self GetCoordinateButton:tagSelected-1];
	
	if (showView == YES) {
		
		// Se anyade a la vista
		[self.view addSubview:tagDetail_.view];
		[self.view addSubview:buttonToDraw];
		
	} else {
		
		// Se oculta
		[tagDetail_.view removeFromSuperview];
		[buttonToDraw removeFromSuperview];
	}
	
}

- (void)getRadarAndBackButtonToTheFront {

	[self.view bringSubviewToFront:radarController_.view];
	[self.view bringSubviewToFront:backButton_];
	
}

#pragma mark Radar mothods

// Cambia los puntos del radar girando la vista que los contiene
- (void)changeRadarsPointsPosition:(double)myazimuth {
	
	if (self.ARorientation == YES) {
		
		[radarController_ moveRadarPoints:myazimuth];
		
	} else {
		
		[radarController_ moveRadarPoints:myazimuth + M_PI/2.0];
		
	}
}

// Resetea el radar
- (void)resetRadar {
	
	[radarController_ resetRadar];
	[radarController_.view removeFromSuperview];
	[radarController_ release]; radarController_ = nil;
	radarHidden_ = YES;
	
}

#pragma mark Metodos para el cambio de orientación

// Selector que se encarga de decidir que hacer cuando se recibe una notificacion de cambio de orienteacion.
- (void)orientationChanged:(NSNotification *)notification {
	
	UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView_) {
		
        isShowingLandscapeView_ = YES;
		self.ARorientation = NO;
		[self rotateRAViewAcordingToOrientation:NO];
		
    } else if (UIDeviceOrientationIsPortrait(deviceOrientation) && isShowingLandscapeView_) {
		
        isShowingLandscapeView_ = NO;
		self.ARorientation = YES;
		[self rotateRAViewAcordingToOrientation:YES];
    }
}

// Cambia el aspecto de la vista de RA rotandola
- (void)rotateRAViewAcordingToOrientation:(BOOL)IsLandscape {
	
	// creación de la ruta de movimiento
	CGMutablePathRef ruta = CGPathCreateMutable();
	CGMutablePathRef rutabutt = CGPathCreateMutable();
	
	// Añadimos una curva a la ruta
	if (IsLandscape == YES) {
		
		CGPathMoveToPoint(ruta,NULL,55.0,425.0);
		CGPathAddLineToPoint(ruta,NULL,255.0,425.0);
		
		CGPathMoveToPoint(rutabutt,NULL,25.0,10.0);
		CGPathAddLineToPoint(rutabutt,NULL,25.0,440.0);
		
	} else {
		
		CGPathMoveToPoint(ruta,NULL,255.0,425.0);
		CGPathAddLineToPoint(ruta,NULL,55.0,425.0);
		
		CGPathMoveToPoint(rutabutt,NULL,25.0,440.0);
		CGPathAddLineToPoint(rutabutt,NULL,25.0,10.0);
	}
	
	// Declaración de la variable de animación
	CAKeyframeAnimation *animacion;
	// Establece sobre qué tipo de propiedad va actuar la animación
	// En este caso es la posición
	animacion = [CAKeyframeAnimation animationWithKeyPath:@"position"];
	// Añadimos la ruta a la animación
	animacion.path = ruta; 
	
	// Establece la duración en segundos
	animacion.duration = 0.6;
	// Indica el número de veces que se va a repetir la animación
	animacion.repeatCount = 0;
	// Indica si la animación volverá al estado inicial
	animacion.autoreverses = NO;
	
	// Añadimos la animación a la capa del elemento que queremos animar
	[radarController_.view.layer addAnimation:animacion forKey:@"animatePosition"];
	
	CAKeyframeAnimation *animacionbutt;
	// Establece sobre qué tipo de propiedad va actuar la animación
	// En este caso es la posición
	animacionbutt = [CAKeyframeAnimation animationWithKeyPath:@"position"];
	// Añadimos la ruta a la animación
	animacionbutt.path = rutabutt; 
	
	// Establece la duración en segundos
	animacionbutt.duration = 0.6;
	// Indica el número de veces que se va a repetir la animación
	animacionbutt.repeatCount = 0;
	// Indica si la animación volverá al estado inicial
	animacionbutt.autoreverses = NO;
	
	// Añadimos la animación a la capa del elemento que queremos animar
	[backButton_.layer addAnimation:animacionbutt forKey:@"animatePosition"];
	
	[radarController_ changeRadarImage:isShowingLandscapeView_];
	
	if (IsLandscape == YES) {
		
		radarController_.view.transform = CGAffineTransformIdentity;
		radarController_.view.frame = CGRectMake(220.0, 380.0, radarController_.view.frame.size.width, radarController_.view.frame.size.height);
		
		backButton_.transform = CGAffineTransformIdentity;
		backButton_.frame = CGRectMake(10.0, 440.0, backButton_.frame.size.width, backButton_.frame.size.height);
		
		if ((tagDetail_.view.superview) || (tagSelected != 0)) {
			tagDetail_.view.transform = CGAffineTransformIdentity;
			tagDetail_.view.frame = CGRectMake(80.0, 100.0, tagDetail_.view.frame.size.width, tagDetail_.view.frame.size.height);
			[tagDetail_ setMIsLandScapeForInstr:NO];
			
			UIButton *buttonToDraw = [self GetCoordinateButton:tagSelected-1];
			buttonToDraw.transform = CGAffineTransformIdentity;
			buttonToDraw.frame = CGRectMake(80.0, 100.0, buttonToDraw.frame.size.width, buttonToDraw.frame.size.height);
		} 

	} else {
		radarController_.view.frame = CGRectMake(10.0, 380.0, radarController_.view.frame.size.width, radarController_.view.frame.size.height);
		radarController_.view.transform = CGAffineTransformMakeRotation(M_PI/2.0);
		
		backButton_.frame = CGRectMake(10.0, 10.0, backButton_.frame.size.width, backButton_.frame.size.height);
		backButton_.transform = CGAffineTransformMakeRotation(M_PI/2.0);
		
		if ((tagDetail_.view.superview) || (tagSelected != 0)) {
			tagDetail_.view.transform = CGAffineTransformMakeRotation((M_PI/2.0));
			tagDetail_.view.frame = CGRectMake(30.0, 150.0, tagDetail_.view.frame.size.width, tagDetail_.view.frame.size.height);
			[tagDetail_ setMIsLandScapeForInstr:YES];
			
			UIButton *buttonToDraw = [self GetCoordinateButton:tagSelected-1];
			buttonToDraw.transform = CGAffineTransformMakeRotation((M_PI/2.0));
			buttonToDraw.frame = CGRectMake(230.0, 150.0, buttonToDraw.frame.size.width, buttonToDraw.frame.size.height);
		} 
	}
	
	// libera la ruta
	CFRelease(ruta);
	CFRelease(rutabutt);
	
}

#pragma mark Vector methods

- (void)GoToDetail:(id)sender {
	
	UIButton *butt = (UIButton*)sender; 
		
	NSLog(@"Button Touch %d",butt.tag);
	
	// Si el boton estaba anteriormente seleccionado
	if ([butt isSelected]) {
		
		// Se deselecciona
		[butt setSelected:NO];
		
		// Se quita el detalle, el cual esta guardado en una instancia de la clase
		[tagDetail_.view removeFromSuperview];
		
		// Y se deselecciona el tag
		tagSelected = 0;
		
	} else {
		
		// Si el boton no estaba seleccionado
		
		// Se da por seleccionado
		[butt setSelected:YES];
		
		// Si habia una seleccion anterior
		if (tagSelected != 0) {
			
			//busco y quito detalle de tagSelected
			UIButton *exselected = [self GetCoordinateButton:tagSelected-1];
			[exselected setSelected:NO];			
			[tagDetail_.view removeFromSuperview];
			
		}
		
		// establezco el nuevo seleccionado
		tagSelected = butt.tag;
		
		// Tomo la vista seleccionada para coger su categoria. Ya no es necesario
		//ARRotatingViewController * arTagViewController = (ARRotatingViewController*)[self getTagController:(tagSelected - 1)];
		
		//añado detalle nuevo, eliminando el anterior
		[tagDetail_ release];
		tagDetail_ = [[overlayDelegate_ detailForCoordinate:[self GetCoordinates:tagSelected-1]] retain];
		
		// Lo anyado al centro de la vista
		[self.view addSubview:tagDetail_.view];
		
		// Lo coloco en el centro dependiendo de la orientacion del terminal
		if (self.ARorientation == NO) {
			
			tagDetail_.view.transform = CGAffineTransformMakeRotation((M_PI/2.0));
			tagDetail_.view.frame = CGRectMake(30.0, 150.0, tagDetail_.view.frame.size.width, tagDetail_.view.frame.size.height);
			[tagDetail_ setMIsLandScapeForInstr:YES];
			
		} else {
			
			tagDetail_.view.frame = CGRectMake(80.0, 100.0, tagDetail_.view.frame.size.width, tagDetail_.view.frame.size.height);
			[tagDetail_ setMIsLandScapeForInstr:NO];
			
		}
		
		//quito la vista pulsada de las visibles entre las giratorias
		UIView *viewToDraw = [self GetCoordinateView:tagSelected-1];
		[viewToDraw setHidden:YES];
		
		// Y coloco el boton en el centro de la imagen de nuevo
		UIButton *buttonToDraw = [self GetCoordinateButton:tagSelected-1];
		[buttonToDraw removeFromSuperview];
		[self.view addSubview:buttonToDraw];
		
		if (self.ARorientation == NO) {
			
			buttonToDraw.transform = CGAffineTransformMakeRotation((M_PI/2.0));
			buttonToDraw.frame = CGRectMake(230.0, 150.0, buttonToDraw.frame.size.width, buttonToDraw.frame.size.height);
			
		} else {
			
			buttonToDraw.frame = CGRectMake(80.0, 100.0, buttonToDraw.frame.size.width, buttonToDraw.frame.size.height);
			
		}
	}
}

- (BOOL)GetLandscapeCondition {
	
	return isShowingLandscapeView_;
	
}

#pragma mark -
#pragma mark Metodos privados


#pragma mark Touch event

// Se redefine el metodo touches began
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
	
	// Si el radar est oculto
	if (radarHidden_ == YES) {
		
		NSLog(@"OverlayViewController - touchesBegan");
		//[radarController.view setHidden:NO];
		//radarController.view.frame = CGRectMake(220.0, 370.0, radarController.view.frame.size.width, radarController.view.frame.size.height);
		//[self.view addSubview:radarController.view];
		//[radarController addPointsToRadarView];
		
		//if ([self ARorientation] == YES) {
			//supportButtons.view.frame = CGRectMake(10.0, 10.0, supportButtons.view.frame.size.width, supportButtons.view.frame.size.height);
			//[supportButtons selectFirstButtonImage:NO];
		//} else {
			//supportButtons.view.transform = CGAffineTransformMakeRotation(M_PI/2.0);
			//supportButtons.view.frame = CGRectMake(270.0, 10.0, supportButtons.view.frame.size.width, supportButtons.view.frame.size.height);
			//[supportButtons selectFirstButtonImage:YES];
		//}
		
		//[self.view addSubview:supportButtons.view];
		
		//CATransition *animation = [CATransition animation];
//		
//		[animation setType:kCATransitionFade];
//		
//		// Set the duration and timing function of the transtion -- duration is passed in as a parameter, use ease in/ease out as the timing function
//		[animation setDuration:0.75];
//		[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
//		
//		[[self.view layer] addAnimation:animation forKey:@"transitionViewAnimation"];
//		
//		radarHidden = NO;
	}
}

#pragma mark update locations

// Metodo que actualiza n veces cada segundo la posicion de las vistas giratorias respecto al usuario
- (void)updateLocations:(NSTimer *)timer {
	
	//NSLog(@"Updating Locations!!!!");
	
	// Si no hay nada que actualizar
	if ([self IsCoordinateViewsEmpty] == YES) {
		
		// Se sale del metodo
		return;
		
	}
	
	//Se anyaden las vistas por primera vez
	[self addViewsIfFirstTime];
	
	int index = 0;
	
	// Iterando sobre cada ARCoordinate de la vista de RA
	for (int i=0;i<[[self coordinates] count];i++) {
		
		ARCoordinate *item = (ARCoordinate*)[[self coordinates] objectAtIndex:i];
		
		// Si no es la ARCoodinate seleccionada
		if ( (tagSelected -1 ) !=i ) {
			
			// Se cogen las vistas
			UIView *viewToDraw = [self GetCoordinateView:i];
			UIButton *buttonToDraw = [self GetCoordinateButton:i];
			
			// Si estan visibles
			if ([self viewportContainsCoordinate:item]) {
				
				// Tomamos el controlador y actualizamos la distancia del mismo
				ARRotatingViewController * viewController = (ARRotatingViewController *)[self getTagController:i];
				CLLocation *controllerLocation = [(ARGeoCoordinate *)item geoLocation];
				[viewController updateDistance:[controllerLocation getDistanceFrom:myLocation_]];
				
				// Comentado para facilitar la depuracion
				//DLog(@"Localicacion de la vista %d: %f, %f", i, controllerLocation.coordinate.latitude, controllerLocation.coordinate.longitude );
				//DLog(@"Distancia de la vista %d: %f", i, [controllerLocation getDistanceFrom:myLocation_]);
				
				// Se realizan operaciones para calcular donde se encuentra la vista y asi aplicar el efecto 3D correctamente
				CGPoint loc = [self pointInView:self.view forCoordinate:item];
				
				CGFloat scaleFactor = 1.0;
				if (self.scaleViewsBasedOnDistance) {
					
					scaleFactor = 1.0 - self.minimumScaleFactor * (item.radialDistance / self.maximumScaleDistance);
					
				}				
				
				float width = viewToDraw.bounds.size.width * scaleFactor;
				float height = viewToDraw.bounds.size.height * scaleFactor;
				
				if (self.ARorientation == YES) {
					
					viewToDraw.frame = CGRectMake(loc.x - width / 2.0 - 30.0, loc.y + height / 2.0 - (BANNER_STEP * item.radialDistance)/self.maximumScaleDistance, width, height);
					buttonToDraw.frame = CGRectMake(loc.x - width / 2.0 - 30.0, loc.y + height / 2.0 - (BANNER_STEP * item.radialDistance)/self.maximumScaleDistance, 100.0, 100.0);
					
				} else {
					
					viewToDraw.frame = CGRectMake(loc.x - width / 2.0 + (BANNER_STEP_L * item.radialDistance)/self.maximumScaleDistance, loc.y - height / 2.0 - 50.0, width, height);
					buttonToDraw.frame = CGRectMake(loc.x - width / 2.0 + (BANNER_STEP_L * item.radialDistance)/self.maximumScaleDistance - 90.0, loc.y - height / 2.0 - 50.0, 100.0, 100.0);
					
				}
				
				[viewToDraw setHidden:NO];
				[buttonToDraw setHidden:NO];
				
				CATransform3D transform = CATransform3DIdentity;
				
				//set the scale if it needs it.
				if (self.scaleViewsBasedOnDistance) {
					//scale the perspective transform if we have one.
					transform = CATransform3DScale(transform, scaleFactor, scaleFactor, scaleFactor);
				}
				
				if (self.rotateViewsBasedOnPerspective) {
					
					transform.m34 = 1.0 / 300.0;
					
					double itemAzimuth = item.azimuth;
					double centerAzimuth = self.centerCoordinate.azimuth;
					if (itemAzimuth - centerAzimuth > M_PI) centerAzimuth += 2*M_PI;
					if (itemAzimuth - centerAzimuth < -M_PI) itemAzimuth += 2*M_PI;
					
					double angleDifference = itemAzimuth - centerAzimuth;
					if (self.ARorientation == NO) {
						
						transform = CATransform3DRotate(transform, M_PI/2.0 , 0, 0, 1);
						
					}
					
					transform = CATransform3DRotate(transform, self.maximumRotationAngle * angleDifference / (VIEWPORT_WIDTH_RADIANS / 2.0) , 0, 1, 0);
					
				}
				
				viewToDraw.layer.sublayerTransform = transform;
				
				//girar los elementos de 90º
				if (self.ARorientation == NO) {
					
					CATransform3D transformbutt = CATransform3DIdentity;
					transformbutt = CATransform3DRotate(transformbutt, M_PI/2.0 , 0, 0, 1);
					buttonToDraw.layer.transform = transformbutt;
					
				} else {
					
					buttonToDraw.transform = CGAffineTransformIdentity;
					
				}				
				
			} else {
				// Si no estan visibles se ocultan hasta que lo vuelvan a estar
				
				[viewToDraw setHidden:YES];
				[buttonToDraw setHidden:YES];
				
			}			
		}
		
		index++;
	}
}

// Anyade las vistas giratorias si es la primera vez que se entra en la vista
- (void)addViewsIfFirstTime {
	
	// Si es la primera vez que se entra, anyadimos las vistas
	if (firstAddingViews == YES) {
		
		firstAddingViews = NO;
		
		// Vista y boton que se anyadiran y que giraran con el movimiento
		UIView *viewToDraw;
		UIButton *buttonToDraw;
		
		for (int i=0;i<[[self coordinates] count];i++) {
			
			// Recogemos las vistas ya creadas
			viewToDraw = [self GetCoordinateView:i];
			buttonToDraw = [self GetCoordinateButton:i];
			
			// Las ocultamos
			[viewToDraw setHidden:YES];
			[buttonToDraw setHidden:YES];
			
			// Y si no tienen vista padre, es decir, no han sido anyadidos a ninguna vista
			if (!(viewToDraw.superview)) {
				
				// Se anyaden a esta vista overlay
				[self.view addSubview:buttonToDraw];
				[self.view sendSubviewToBack:buttonToDraw];
				[self.view addSubview:viewToDraw];
				[self.view sendSubviewToBack:viewToDraw];
				
			}				
		}
	}	
}

#pragma mark -
#pragma mark Redefinicion de metodos de LocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
	
	// Se hace lo anterior
	[super locationManager:manager didUpdateToLocation:newLocation fromLocation:oldLocation];
	
	// Registramos la posicion actual
	[myLocation_ release];
	myLocation_ = [ newLocation retain];
	
}

@end
